/*!
    \copyright  Copyright (c) 2024 - 2025 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    @{
        \ingroup    adkfs
        \brief      Describes the interface that needs to be provided by adkfs providers

*/

#include "adkfs_provider_if.h"
#include "adkfs_provider_init.h"

#include <logging.h>
#include <stdint.h>
#include <string.h>


static adkfs_provider_if_t* providers[ADKFS_MAX_PROVIDERS];

void AdkFs_RegisterProvider(const adkfs_provider_if_t* interface)
{
    PanicNull(interface);
    PanicFalse(strlen(interface->root_path) <= ADKFS_MAX_LEN_PROVIDER_ROOT);

    int free_slot = -1;
    for (unsigned i = 0; i < ADKFS_MAX_PROVIDERS; i++)
    {
        if (!providers[i])
        {
            if (free_slot < 0)
            {
                free_slot = i;
            }
        }
        else
        {
            if (0 == strncmp(providers[i]->root_path, interface->root_path, ADKFS_MAX_LEN_PROVIDER_ROOT))
            {
                DEBUG_LOG_PANIC("Only one provider per root path is allowed. Existing provider=0x%p at idx=%u, New provider=0x%p", providers[i], i, interface);
            }
        }
    }
    providers[free_slot] = interface;

    if (interface->Init && !interface->Init(AdkFs_ProviderInitGetTask()))
    {
        AdkFs_ProviderInitAddPendingAsync(interface->Init);
    }
}

const adkfs_provider_if_t* AdkFs_GetProvider(const char *path)
{
    for (uint8_t i = 0; i < ADKFS_MAX_PROVIDERS; i++)
    {
        if (('\0' != providers[i]->root_path[0]) && (0 == strncmp(path, providers[i]->root_path, strlen(providers[i]->root_path))))
        {
            return providers[i];
        }
    }
    return NULL;
}
